#include "adc.h"
#include "type.h"
#include "ps2kbd.h"
#include "lcd.h"
#include "led.h"
#include "uart.h"
#include "vcom.h"
#include "i2c.h"
#include "74HC595.h"
#include "fs_api.h"
#include "riffwave.h"
#include "efs.h"
#include "vga.h"

#define AT24C256_I2C_ADDRESS 0xA0
#define FIRST_WORD_ADDRESS 0
#define SECOND_WORD_ADDRESS 0

#define UART0_TEXT "\n\r Testing UART0 NGX's BlueBoard \n\r BlueBoard Revision : 1 \n\r Firmware Version: 1 \n\r For more information on BlueBoard visit www.ngxtechnologies.com"
#define UART1_TEXT "\n\r Testing UART1 NGX's BlueBoard \n\r BlueBoard Revision : 1 \n\r Firmware Version: 1 \n\r For more information on BlueBoard visit www.ngxtechnologies.com"
#define USB_TEXT "\n\r Testing USB NGX's BlueBoard \n\r BlueBoard Revision : 1 \n\r Firmware Version: 1 \n\r For more information on BlueBoard visit www.ngxtechnologies.com"
#define SD_CARD_TEXT "\n\r Testing SD card NGX's BlueBoard \n\r BlueBoard Revision : 1 \n\r Firmware Version: 1 \n\r For more information on BlueBoard visit www.ngxtechnologies.com"
#define BUZZER BIT25
#define BUZZER_DIR FIO1DIR
#define BUZZER_SET FIO1SET
#define BUZZER_CLR FIO1CLR

#define GET_SCALED_LED_MASK_BUF_INDEX(val) (val/114)
extern void lpc2000_debug_devopen( int(*put)(int) );
extern void lpc2000_debug_printf(char const *format, ...);

const U8 led_mask_buf[] = {0,1,3,7,0xF,0x1F,0x3F,0x7F,0xFF};

extern EmbeddedFileSystem efs;

/**
********************************************************************************************
	Function Name :	is_valid_ascii()

	Description :
	
	Input :	Void

	Output : Void

	Note :
**********************************************************************************************
*/
U8 is_valid_ascii(S8 key)
{
  U8 retval = FALSE;
  
  if(key >= ' ' && key <= '~')
    retval = TRUE;

  return retval;
}

/**
********************************************************************************************
	Function Name :	process_lcd()

	Description :
	
	Input :	Void

	Output : Void

	Note :
**********************************************************************************************
*/
void process_lcd(void)
{
  S8 key;
  static U8 position = 0;
	
  key = xgetkey();
  if(is_valid_ascii(key))
  {
    lcd_gotoxy(LINE2, position);
    lcd_putchar(key);
    if(position == MAX_CHAR_IN_ONE_LINE)
    {
      lcd_clear();
      position = 0;
    }		
    position++;
  }
}

/**
********************************************************************************************
	Function Name :	process_adc()

	Description :
	
	Input :	Void

	Output : Void

	Note :
**********************************************************************************************
*/
void process_adc(void)
{
  U16 adc_value = 0;
  U8 index = 0;

  adc_value = adc_read(ADC0, CHANNEL_3);
  index = GET_SCALED_LED_MASK_BUF_INDEX(adc_value);
  if(index > sizeof(led_mask_buf))
    index = sizeof(led_mask_buf) -1;
  turn_on_led(led_mask_buf[index]);
}

/**
*******************************************************************************
  Function Name : test_uart0()

  Description :	 

  Input :	

  Output :	none

  Note : 
*******************************************************************************
*/
void test_uart0(void)
{
  U8 buffer[] = UART0_TEXT;

  uart1Write((char*)buffer, sizeof(buffer));
}

static U16 uart0_count = 0;
void test_my_uart0(U8 c)
{
  uart0_count++;

  U8 buffer[] = "\n\r UART0 Got Char:";
  U8 this_char;
  U8 end_line[] = "\n\r";
  if (c >= ' ' && c <= '~')
     this_char = c;
  else 
     this_char = '*';

//  U8 buffer[] = UART0_TEXT;
  
  uart0Write((char*)&buffer, sizeof(buffer));
  uart0Write((char*)&this_char, 1);
  uart0Write((char*)&end_line, sizeof(end_line));
  if (c == 'p' || c == 'P')
     reset_play();
  if (c == 'b') 
  {
      BUZZER_DIR |= BUZZER;
      BUZZER_CLR |= BUZZER;	
  }
  if (c == 'B') 
  {
    BUZZER_DIR |= BUZZER;
    BUZZER_SET |= BUZZER;
  }
}

unsigned int Step_Delay = 100;       // delay(10000) is about 100mS
                                     // delay(500)   is 5mS
U8           Motor_Switch = 's';     // s=stop g=go

// Stepping motor code
void change_step_delay(U8 ch)
{
    if (ch == '+')
    {
      Step_Delay += 5;      // increase by 5mS
    }
    if (ch == '-')
    {
      if (Step_Delay > 10)
        Step_Delay -= 5;
    }
    lpc2000_debug_printf("Step Delay = %d\n",Step_Delay);
}

void start_motor(void)
{
  Motor_Switch = 'g';     // start the motor
}

void  start_step(void)
{
     lpc2000_debug_printf("Enter routine start_step\n");
     int i;
// Clearing the bit turns the port on.
// ports are P1.22 (BIT22), P1.23 (BIT23), and P1.34 (BIT24)
     Motor_Switch = 's';     // Set motor switch to stop

  for (i=0; i<50; i++)
  {
      FIO1CLR |= BIT24;     //  STATE_1   011
      tn_task_sleep(Step_Delay);
 
      FIO1SET |= BIT24;
      FIO1CLR |= BIT23;     //  STATE_2   101
      tn_task_sleep(Step_Delay);

      FIO1SET |= BIT23;
      FIO1CLR |= BIT22;     //  STATE_3   110
      tn_task_sleep(Step_Delay);

      FIO1SET |= BIT22;     //  reset
  }

  FIO1SET |= ( BIT24 | BIT23 | BIT22 );    //  STATE_OFF 111
// Now Reverse
  for (i=0; i<50; i++)
  {
      FIO1CLR |= BIT22;     //  STATE_3   110
      tn_task_sleep(Step_Delay);

      FIO1SET |= BIT22;
      FIO1CLR |= BIT23;    //  STATE_2   101
      tn_task_sleep(Step_Delay);

      FIO1SET |= BIT23;
      FIO1CLR |= BIT24;    //  STATE_1   011
      tn_task_sleep(Step_Delay);

      FIO1SET |= BIT24;    //  reset
  }
  FIO1SET |= ( BIT24 | BIT23 | BIT22 );   //  STATE_OFF 111
}


/**
*******************************************************************************
  Function Name : test_uart1()

  Description :	 

  Input :	

  Output :	none

  Note : 
*******************************************************************************
*/
void test_uart1(void)
{
  U8 buffer[] = UART1_TEXT;

  uart1Write((char*)buffer, sizeof(buffer));
}

/**
*******************************************************************
	Funtion Name : test_usb()

	Description  : 

	Input        : 

	Output       : None

	Note         :
*****************************************************************
*/
void test_usb(void)
{
  U8 buffer[] = USB_TEXT;

  while((VCOM_write(sizeof(buffer), buffer)) != sizeof(buffer));
}

/**
*******************************************************************
	Funtion Name : test_sd_card()

	Description  : 

	Input        : 

	Output       : None

	Note         :
*****************************************************************
*/
U8 buf[513] = {0};   // Make buffer global to avoid overflow on the stack
U8 outbuf[] = "Data Record for outfile xxxxxxxx\n";

void test_sd_card(void)
{
File myfile;
File outfile;
// U8 buf[200] = {0};

euint32 chars_read = 0;
U8 r;

  if(!fs_init())
  {
    set_file_system_status(TRUE);
    lcd_clear();
    lcd_putstring(LINE1,"SD card - PASS");

    if(!fopen(&myfile,(S8*)"arm.cxx",'r'))
    {
       chars_read = file_read(&myfile,sizeof(buf),(U8*)&buf);
//       buf[chars_read] = '\0';
       lpc2000_debug_printf("buffer = %s\n",buf);
       file_fclose(&myfile);
    }

    if(!fopen(&myfile,(S8*)"copy.txt",'r'))
    {
       while ((chars_read = file_read(&myfile,512,(U8*)&buf)))
       {
       buf[chars_read] = '\0';
       lpc2000_debug_printf("%s",buf);
//       delay(100000);
       }
       lpc2000_debug_printf("\n\n");
       file_fclose(&myfile);
    }

    if (!fopen(&outfile,(S8*)"out2.txt",'r'))
    {
       U8 r;
       lpc2000_debug_printf("found file out.txt2\n");
       while ((chars_read = file_read(&outfile,512,(U8*)&buf)))
       {
       buf[chars_read] = '\0';
       lpc2000_debug_printf("%s",buf);
//       delay(100000);
       }
       lpc2000_debug_printf("\n\n");
       file_fclose(&outfile);
//       fs_close();
       r = delete_file((U8*)"out2.txt");
       fs_close();
       lpc2000_debug_printf("delete_file returned %d\n",r);
    } else {

      r = fopen(&outfile,(S8*)"out2.txt",'a');
      lpc2000_debug_printf("fopen for append returned %d\n",r);
      if(!r)
      {
        lpc2000_debug_printf("writing to file out2.txt\n");
        for (int i=0; i<10; i++)
        {
           file_write(&outfile,sizeof(outbuf),(U8*)&outbuf);
        }
         file_fclose(&outfile);
         fs_close();
      }
    }
    fs_umount(&efs.myFs);
  }
  else
  {
    lcd_clear();
    lcd_putstring(LINE1,"SD card - FAIL");
  }
}

/**
*******************************************************************
	Funtion Name : test_i2c_at24c256_flash()

	Description  : 

	Input        : 

	Output       : None

	Note         :
*****************************************************************
*/

void test_i2c_at24c256_flash(void)
{
  U8 i=0;
  U8 status=1;
  U8 buf[128];

  for(i=0;i<sizeof(buf);i++)
    buf[i] = i;
  
  m24xx_write(EEPROM_24XX256, 0 , 0 , (char *)buf , sizeof(buf));

  for(i=0;i<sizeof(buf);i++)
    buf[i] = 0;

  m24xx_read(EEPROM_24XX256, 0 , 0 , (char *)buf , sizeof(buf));

  for(i=0;i<sizeof(buf);i++)
  {
    if(buf[i] != i)
    {
      status = 0;
      break;
    }    
  }

  if(status == 1)
  {
    lcd_putstring(LINE2,"I2C FLASH PASS");
  }
  else
  {
    lcd_putstring(LINE2,"I2C FLASH FAIL");
  }
}


